package com.cssw.fyzb.tps.service.auth.tecent;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cssw.fyzb.tps.config.auth.AccessTokenConfig;
import com.cssw.fyzb.tps.exception.BizException;
import com.cssw.fyzb.tps.util.HttpUtil;
import com.cssw.fyzb.tps.util.TimeUtil;
import com.ydn.simplecache.SimpleCache;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.cssw.fyzb.tps.util.Bizs.ACCESS_TOKEN_FAIL;

/**
 * @Author zhouxu
 * @create 2020-09-14 21:10
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class AccessToken implements Serializable {
    private static final Logger logger = LoggerFactory.getLogger(AccessToken.class);

    public static final String KEY_PREX = "access_token_";
    @Autowired
    private SimpleCache simpleCache;

    private String url;
    private String appId;
    private String secret;
    /**
     * 授权类型，默认值为：client_credential（必须小写）
     */
    private String grantType;
    /**
     * 版本号，默认值为：1.0.0
     */
    private String version;

    public AccessTokenConfig getAccessToken() throws Exception {
//         TOKEN 未过期，从缓存中取
        AccessTokenConfig result = simpleCache.get(KEY_PREX + appId);
        if (result != null && timeOutCheck(result.getExpireTime(), result.getExpireIn())) {
            return result;
        }

        Map<String, Object> param = new HashMap<>();
        param.put("app_id", appId);
        param.put("secret", secret);
        param.put("grant_type", grantType);
        param.put("version", version);
        logger.debug("params: " + JSON.toJSONString(param));

        long startTime = System.currentTimeMillis();
        String json = HttpUtil.get(url, param);
        long endTime = System.currentTimeMillis();
        logger.debug("userTime: " + (endTime - startTime));

        // TOKEN 已过期重新请求
        result = parseObject(json);
        if (result == null || !HttpResult.STATUS_SUCCESS.equals(result.getCode())) {
            logger.error(json);
            throw new BizException(ACCESS_TOKEN_FAIL.code, ACCESS_TOKEN_FAIL.message);
        }

        // 加缓存
        simpleCache.delete(KEY_PREX + appId);
        simpleCache.put(KEY_PREX + appId, result);

        return result;

    }

    private AccessTokenConfig parseObject(String json) {
        JSONObject jsonObject = JSON.parseObject(json);
        String code = jsonObject.getString("code");
        String transactionTime = jsonObject.getString("transactionTime");
        String access_token = jsonObject.getString("access_token");
        boolean success = jsonObject.getBoolean("success");
        String expire_in = jsonObject.getString("expire_in");
        String expire_time = jsonObject.getString("expire_time");

        AccessTokenConfig result = new AccessTokenConfig();
        result.setCode(code);
        result.setTransactionTime(transactionTime);
        result.setSuccess(success);
        result.setAccessToken(access_token);
        result.setExpireIn(expire_in);
        result.setExpireTime(expire_time);

        return result;

    }

    private boolean timeOutCheck(String expireTime, String expireIn) {
        Date expire_time = TimeUtil.parse(expireTime, TimeUtil.FORMAT_DEFAULT);
        Date now = new Date();
        long between = (expire_time.getTime() - now.getTime()) / 1000;
        if (between > 0 && Long.valueOf(expireIn) > between) {
            return true;
        }

        return false;
    }


    /**
     * 出参报文：
     * {
     * "code":"0","msg":"请求成功",
     * "transactionTime":"20151022043831",
     * "access_token":"accessToken_string",
     * "expire_time":"20151022043831",
     * "expire_in":"7200"
     * }
     */
    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class HttpResult implements Serializable {
        public static final String STATUS_SUCCESS = "0";

        private String code;
        private String transactionTime;
        private boolean success;
        private String access_token;
        private String expire_in;
        private String expire_time;

    }


    public static void main(String[] args) throws Exception {
        String url = "https://idasc.webank.com/api/oauth2/access_token";
        //ID: TIDAD0fb
        //
        //Secret: h7g0DtzOTBHojWpLTqWr00YqmKKi1JnaPYjPFKSI8YJDblUKFm5EiTNqVksDFkHs
        String appId = "TIDAD0fb";
        String secret = "h7g0DtzOTBHojWpLTqWr00YqmKKi1JnaPYjPFKSI8YJDblUKFm5EiTNqVksDFkHs";
        String grantType = "client_credential";
        String version = "1.0.0";

        AccessToken accessToken = new AccessToken();
        accessToken.setUrl(url);
        accessToken.setSecret(secret);
        accessToken.setAppId(appId);
        accessToken.setGrantType(grantType);
        accessToken.setVersion(version);

        AccessTokenConfig result = accessToken.getAccessToken();
        logger.debug(result.toString());

    }

}
